home *** CD-ROM | disk | FTP | other *** search
/ Game Programming in C++ - Start to Finish / GameProgrammingS.iso / Peon / PeonSDK-Win32-1.0.0.exe / {app} / PeonMain / include / CEGUI / CEGUIEvent.h < prev    next >
Encoding:
C/C++ Source or Header  |  2005-09-07  |  9.6 KB  |  347 lines

  1. /************************************************************************
  2.     filename: CEGUIEvent.h
  3.     created:  15/10/2004
  4.     authors:  Paul D Turner (High-level design) 
  5.             Gerald Lindsly (Coder)
  6.     
  7.     purpose:  Defines interface for Event class
  8. *************************************************************************/
  9. /*************************************************************************
  10.     Crazy Eddie's GUI System (http://www.cegui.org.uk)
  11.     Copyright (C)2004 - 2005 Paul D Turner (paul@cegui.org.uk)
  12.  
  13.     This library is free software; you can redistribute it and/or
  14.     modify it under the terms of the GNU Lesser General Public
  15.     License as published by the Free Software Foundation; either
  16.     version 2.1 of the License, or (at your option) any later version.
  17.  
  18.     This library is distributed in the hope that it will be useful,
  19.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  21.     Lesser General Public License for more details.
  22.  
  23.     You should have received a copy of the GNU Lesser General Public
  24.     License along with this library; if not, write to the Free Software
  25.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  26. *************************************************************************/
  27. #ifndef _CEGUIEvent_h_
  28. #define _CEGUIEvent_h_
  29.  
  30. #if defined (_MSC_VER)
  31. #    pragma warning(push)
  32. #    pragma warning(disable : 4786)
  33. #    pragma warning(disable : 4251)
  34. #    if !defined (_MSC_EXTENSIONS)
  35. #        pragma warning (disable : 4224)
  36. #    endif
  37. #endif
  38.  
  39. #include "CEGUIBase.h"
  40. #include "CEGUIString.h"
  41. #include "CEGUIEventArgs.h"
  42. #include "CEGUIRefPtr.h"
  43.  
  44. #include <map>
  45.  
  46.  
  47. // Start of CEGUI namespace section
  48. namespace CEGUI
  49. {
  50.  
  51. /* The base class for the various binders.  This provides
  52.    a consistent interface for firing functions bound to an event.
  53. */
  54. template <typename Ret, typename Args>
  55. class SubscriberInterface {
  56. public:
  57.   virtual Ret operator()(Args) const = 0;
  58.   virtual ~SubscriberInterface() {}
  59. };
  60.  
  61.  
  62. /* This class binds a free function. */
  63. template <typename Ret, typename Args>
  64. class _freeBinder : public SubscriberInterface<Ret,Args>
  65. {
  66. public:
  67.   virtual Ret operator()(Args args) const 
  68.   {
  69.     return d_f(args);
  70.   }
  71.   typedef Ret (*SlotFunction)(Args);
  72.   _freeBinder(SlotFunction f) : d_f(f) {}
  73. protected:
  74.   SlotFunction d_f;
  75. };
  76.  
  77.  
  78. /* This class binds a copy of a functor. */
  79. template <class Functor, typename Ret, typename Args>
  80. class _functorBinder : public SubscriberInterface<Ret,Args>
  81. {
  82. public:
  83.   virtual Ret operator()(Args args) const 
  84.   {
  85.     return d_f(args);
  86.   }
  87.   _functorBinder(const Functor& f) : d_f(f) {}
  88. protected:
  89.   Functor d_f;
  90. };
  91.  
  92.  
  93. /* This class binds a member function along with a target
  94.    object. */
  95. template <class T, typename Ret, typename Args>
  96. class _memberBinder : public SubscriberInterface<Ret,Args>
  97. {
  98.   typedef Ret (T::*F)(Args);
  99. public:
  100.   virtual Ret operator()(Args args) const
  101.   {
  102.     return (d_t->*d_f)(args);
  103.   }
  104.   _memberBinder(F f, T* t) : d_f(f), d_t(t) {}
  105. protected:
  106.   F  d_f;
  107.   T* d_t;
  108. };
  109.  
  110.  
  111. /* This template describes the Subscriber class.  It is a wrapper
  112.    for a pointer to a SubscriberInterface with various constructors
  113.    that will by implicit conversion construct the various binders. */
  114. template <typename Ret, typename Args>
  115. class SubscriberTemplate
  116. {
  117. public:
  118.   Ret operator()(Args args) const
  119.   {
  120.     return (*d_si)(args);  // call the bound function
  121.   }
  122.  
  123.   typedef Ret (*SlotFunction)(Args);
  124.  
  125.   // construct from a free function
  126.   SubscriberTemplate(SlotFunction f)
  127.   {
  128.     d_si = new _freeBinder<Ret,Args>(f);
  129.   }
  130.  
  131.   // construct from a member function and a pointer to the target object.
  132.   template <class T>
  133.   SubscriberTemplate(Ret (T::*f)(Args), T* target)
  134.   {
  135.     d_si = new _memberBinder<T,Ret,Args>(f, target);
  136.   }
  137.  
  138.   // construct from a generalized functor by copying it
  139.   template <typename Functor> 
  140.   SubscriberTemplate(const Functor& f)
  141.   {
  142.     d_si = new _functorBinder<Functor,Ret,Args>(f);
  143.   }
  144.  
  145.   /* construct from a preconstructed SubscriberInterface.
  146.      used for SubscriberRef(). */
  147.   SubscriberTemplate(SubscriberInterface<Ret,Args>* si) : d_si(si) {}
  148.  
  149.   // copy constructor
  150.   SubscriberTemplate(const SubscriberTemplate<Ret,Args>& copy) : d_si(copy.d_si) {}
  151.  
  152.   // 'less than' comparable for insertion in a map
  153.   bool operator<(const SubscriberTemplate<Ret,Args>& rhs) const { return d_si < rhs.d_si; }
  154.  
  155.   // release the binding -- called upon disconnection
  156.   void release() const
  157.   {
  158.     delete d_si;
  159.   }
  160.  
  161. protected:
  162.   SubscriberInterface<Ret,Args>* d_si;
  163. };
  164.  
  165.  
  166. /* This class binds a const reference to a generalized functor.
  167.    Sometimes it may not be appropriate for the functor to be
  168.    cloned.  In which case, use SubscriberRef() (which uses this). */
  169. template <class Functor, typename Ret, typename Args>
  170. class _refBinder : public SubscriberInterface<Ret,Args>
  171. {
  172. public:
  173.   virtual Ret operator()(Args args) const
  174.   {
  175.     return d_f(args);
  176.   }
  177.   _refBinder(const Functor& f) : d_f(f) {}
  178. protected:
  179.   const Functor& d_f;
  180. };
  181.  
  182. /* This helper function produces a const reference binding */
  183. template <class Functor>
  184. SubscriberInterface<bool, const EventArgs&>*
  185. SubscriberRef(const Functor& f)
  186. {
  187.   return new _refBinder<Functor,bool,const EventArgs&>(f);
  188. }
  189.  
  190.  
  191. /*!
  192. \brief
  193.     Defines an 'event' which can be subscribed to by interested parties.
  194.  
  195.     An Event can be subscribed by a function, a static member function, or a function object.  Whichever option
  196.     is taken, the function signature needs to be as follows
  197.     \par
  198.     <em>bool function_name(const EventArgs& args);</em>
  199.     \note
  200.         An Event object may not be copied.
  201. */
  202. class CEGUIEXPORT Event
  203. {
  204. public:
  205.     class ConnectionInterface : public Referenced {
  206.     public:
  207.         virtual bool connected() { return false; }
  208.         virtual void disconnect() {}
  209.     };
  210.     typedef RefPtr<ConnectionInterface> Connection;
  211.  
  212.  
  213.     class ScopedConnection {
  214.     public:
  215.         ScopedConnection(Connection conn_) : conn(conn_) {}
  216.         ~ScopedConnection() { conn->disconnect(); }
  217.         Connection conn;
  218.     };
  219.  
  220.  
  221.     typedef SubscriberTemplate<bool, const EventArgs&> Subscriber;
  222.     typedef int Group;
  223.  
  224.     /*************************************************************************
  225.         Construction and Destruction
  226.     *************************************************************************/
  227.     /*!
  228.     \brief
  229.         Constructs a new Event object with the specified name
  230.     */
  231.     Event(const String& name);
  232.  
  233.     /*!
  234.     \brief
  235.         Destructor for Event objects
  236.     */
  237.     virtual ~Event(void);
  238.  
  239.  
  240.     /*!
  241.     \brief
  242.         Return the name given to this Event object when it was created.
  243.  
  244.     \return
  245.         String object containing the name of the Event object.
  246.     */
  247.     const String& getName(void) const    {return d_name;}
  248.  
  249.  
  250.     /*!
  251.     \brief
  252.         Subscribes some function / object to the Event
  253.  
  254.     \param subscriber
  255.         A function, static member function, or function object, with the signature void function_name(const EventArgs& args)
  256.  
  257.     \return
  258.         A Connection pointer which can be used to disconnect (unsubscribe) from the Event, and to check the connection state.
  259.     */
  260.     Connection subscribe(Subscriber subscriber) { return subscribe(0, subscriber); }
  261.  
  262.  
  263.     /*!
  264.     \brief
  265.         Subscribes some function / object to the Event
  266.  
  267.     \param group
  268.         The Event group to subscribe to, subscription groups are called in ascending order, followed by subscriptions with no group.
  269.         connections to the same group may be called in any order.
  270.  
  271.     \param subscriber
  272.         A function, static member function, or function object, with the signature void function_name(const EventArgs& args)
  273.  
  274.     \return
  275.         A Connection which can be used to disconnect (unsubscribe) from the Event, and to check the connection state.
  276.     */
  277.     Connection subscribe(Group group, Subscriber subscriber);
  278.   
  279.  
  280.     /*
  281.     \brief
  282.         Fires the event.  All event subscribers get called in the appropriate sequence.
  283.  
  284.     \param args
  285.         An object derived from EventArgs to be passed to each event subscriber.
  286.  
  287.     \return
  288.         Nothing.
  289.     */
  290.     void    operator()(EventArgs& args);
  291.  
  292. private:
  293.     /*************************************************************************
  294.         Copy constructor and assignment are not allowed for events
  295.     *************************************************************************/
  296.     Event(const Event& evt)    {}
  297.     Event& operator=(const Event& evt)    {return *this;}
  298.  
  299.     /*
  300.     \brief
  301.         removes the subscriber from the event.
  302.  
  303.     \param subscriber
  304.         A pointer to a SubscriberInterface which is to be removed from the event.
  305.  
  306.     \return
  307.         - true, if the subscriber was registered with the event in the specified group and it was removed.
  308.         - false, if not.
  309.     */
  310.     bool unsubscribe(Subscriber subscriber, Group group=0);
  311.  
  312.     class GroupSubscriber {
  313.     public:
  314.         Group group;
  315.         Subscriber subscriber;
  316.         GroupSubscriber(Group group_, Subscriber subscriber_) 
  317.             : group(group_), subscriber(subscriber_) {}
  318.     };
  319.  
  320.     struct ltGroupSubscriber
  321.     {
  322.         bool operator()(const GroupSubscriber& gs1, const GroupSubscriber& gs2) const
  323.         {
  324.             return gs1.group <  gs2.group ||
  325.                 gs1.group == gs2.group && gs1.subscriber < gs2.subscriber;
  326.         }
  327.     };
  328.     typedef std::map<GroupSubscriber, Connection, ltGroupSubscriber> ConnectionOrdering;
  329.  
  330.  
  331.     /*************************************************************************
  332.         Implementation Data
  333.     *************************************************************************/
  334.     const String    d_name;        //!< Name of this event
  335.     ConnectionOrdering connectionOrdering;
  336.     friend class ConnectionImpl;
  337. };
  338.  
  339.  
  340. } // End of  CEGUI namespace section
  341.  
  342. #if defined(_MSC_VER)
  343. #    pragma warning(pop)
  344. #endif
  345.  
  346. #endif    // end of guard _CEGUIEvent_h_
  347.